<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
   <HEAD>
      <TITLE>GA PROTOTYPE FOR RANKING SERVICE</TITLE>
   </HEAD>
   <BODY>
      <P>GA PROTOTYPE FOR RANKING SERVICE!</br>
		<?php
			//Class of Genetic Algorithm
			class GA {
				var $db;
				//var $get_by_time;
				var $upper_rank;
				var $lower_rank;
				var $road= array();
				var $rs;
				var $new_connections;
				var $root_id;
				var $end_id;

				//Construction Function
				function GA($link){
					$this->db= $link;
					$this->upper_rank= $this->lower_rank= 0;
					
					$this->get_active_ranking();

					$this->copy_current_ranking();
					//$this->get_by_time= time();
				}

				function get_new_connection(){
					$select_query = "select * from rs_post ORDER BY posted_time ASC";
					return $result= mysql_query($select_query,$this->db);
				}

				function check_connection_weight($upper_id, $lower_id){
					//Update "is_connected" field and "weight"
					$select_weight_query = "select * from rs_connection WHERE upper_content_id=".$upper_id." AND lower_content_id=".$lower_id;
					$result_weight_1= mysql_query($select_weight_query,$this->db);
					$row_weight_1= mysql_fetch_array($result_weight_1);

					$select_weight_query = "select * from rs_connection WHERE upper_content_id=".$lower_id." AND lower_content_id=".$upper_id;
					$result_weight_2= mysql_query($select_weight_query,$this->db);
					if(mysql_num_rows($result_weight_2)==1){
						$row_weight_2= mysql_fetch_array($result_weight_2);

						if($row_weight_1['weight']+1>$row_weight_2['weight']){
							$update_query= "UPDATE rs_connection SET  is_connected=1 WHERE upper_content_id=".$upper_id." AND lower_content_id=".$lower_id;
							mysql_query($update_query,$this->db);

							$update_query= "UPDATE rs_connection SET is_connected=0 WHERE upper_content_id=".$lower_id." AND lower_content_id=".$upper_id;
							mysql_query($update_query,$this->db);
							return 0;
						}
						else if(($row_weight_1['weight']+1)==$row_weight_2['weight']){
							$update_query= "UPDATE rs_connection SET  is_connected=0 WHERE upper_content_id=".$upper_id." AND lower_content_id=".$lower_id;
							mysql_query($update_query,$this->db);

							$update_query= "UPDATE rs_connection SET is_connected=0 WHERE upper_content_id=".$lower_id." AND lower_content_id=".$upper_id;
							mysql_query($update_query,$this->db);

							return 1;
						}
						else{
							$update_query= "UPDATE rs_connection SET  is_connected=0 WHERE upper_content_id=".$upper_id." AND lower_content_id=".$lower_id;
							mysql_query($update_query,$this->db);

							$update_query= "UPDATE rs_connection SET is_connected=1 WHERE upper_content_id=".$lower_id." AND lower_content_id=".$upper_id;
							mysql_query($update_query,$this->db);
							return 2;
						}
					}
					else{
						$update_query= "UPDATE rs_connection SET  is_connected=1 WHERE upper_content_id=".$upper_id." AND lower_content_id=".$lower_id;
						mysql_query($update_query,$this->db);
						return 3;
					}//End update "is_connected" field and "weight"
				}
				
				function check_upper_connection($from_content_id, $update_step){
					$select_from_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$from_content_id;
					$result_from_rank= mysql_query($select_from_rank,$this->db);
					$row_from_rank = mysql_fetch_array($result_from_rank);
					//$row_from_rank[$this->rs];

					$select_query = "select * from rs_connection WHERE lower_content_id=".$from_content_id." AND is_connected=1";
					$result= mysql_query($select_query,$this->db);
					if(mysql_num_rows($result)==0) return 2;//Lift to Root of Ranking
					while($row = mysql_fetch_array($result)){
						//echo $row['upper_content_id'];
						$select_current_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$row['upper_content_id'];
						$result_current_rank= mysql_query($select_current_rank,$this->db);
						$row_current_rank = mysql_fetch_array($result_current_rank);
						//echo " ".$row_current_rank[$this->rs];
						if(($row_from_rank[$this->rs]-$row_current_rank[$this->rs])<= $update_step) return 0;//Keep current rank
					}
					return 1;//Lift $update_step of rank
				}

				function lift_rank($from_content_id, $update_step){
					$select_from_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$from_content_id;
					$result_from_rank= mysql_query($select_from_rank,$this->db);
					$row_from_rank = mysql_fetch_array($result_from_rank);
					//$row_from_rank[$this->rs];

					switch($this->check_upper_connection($from_content_id, $update_step)){
						case 0:
							if($this->root_id== $from_content_id) $update=1;
							else{
								$nearest_upper_rank= 0;
								$select_query = "select * from rs_connection WHERE lower_content_id=".$from_content_id." AND is_connected=1";
								$result= mysql_query($select_query,$this->db);

								while($row = mysql_fetch_array($result)){
									$select_current_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$row['upper_content_id'];
									$result_current_rank= mysql_query($select_current_rank,$this->db);
									$row_current_rank = mysql_fetch_array($result_current_rank);
									if($nearest_upper_rank==0) $nearest_upper_rank= $row_current_rank[$this->rs];
									if($nearest_upper_rank < $row_current_rank[$this->rs]) $nearest_upper_rank= $row_current_rank[$this->rs];
									//if(($row_from_rank[$this->rs]-$row_current_rank[$this->rs])<= $update_step) return 0;//Keep current rank
								}

								$update_step= abs($row_from_rank[$this->rs]-$nearest_upper_rank-1);
							}
							break;
						case 1:
							break;
						case 2:
							$update_step= $row_from_rank[$this->rs]-1;
							break;
					}
					if($update_step== 0) return 0;
					else{
						if($this->root_id== $from_content_id) {
							$select_prior_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$this->end_id;
							$result_prior_rank= mysql_query($select_prior_rank,$this->db);
							$row_prior_rank = mysql_fetch_array($result_prior_rank);
							//$row_prior_rank[$this->rs];
							$update_query= "UPDATE ff_rs_content SET ".$this->rs."='".($row_prior_rank[$this->rs]+$update)."' WHERE id=".$from_content_id;
							mysql_query($update_query,$this->db);

							$select_query = "select * from rs_connection WHERE upper_content_id=".$from_content_id." AND is_connected=1";
							$result= mysql_query($select_query,$this->db);

							while($row = mysql_fetch_array($result)){
								$this->down_rank($row['lower_content_id'], $update);//$row_prior_rank[$this->rs]+1-$row_from_rank[$this->rs]);
							}
						}
						else {
							$update_query= "UPDATE ff_rs_content SET ".$this->rs."='".($row_from_rank[$this->rs]-$update_step)."' WHERE id=".$from_content_id;
							mysql_query($update_query,$this->db);

							$select_query = "select * from rs_connection WHERE upper_content_id=".$from_content_id." AND is_connected=1";
							$result= mysql_query($select_query,$this->db);

							while($row = mysql_fetch_array($result)){
								$this->lift_rank($row['lower_content_id'], $update_step);
							}
						}
					}
					return 1;
				}
				
				function down_rank($from_content_id, $update_step){
					$select_from_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$from_content_id;
					$result_from_rank= mysql_query($select_from_rank,$this->db);
					$row_from_rank = mysql_fetch_array($result_from_rank);
					//$row_from_rank[$this->rs];
					
					$update_query= "UPDATE ff_rs_content SET ".$this->rs."='".($row_from_rank[$this->rs]+$update_step)."' WHERE id=".$from_content_id;
					mysql_query($update_query,$this->db);

					$select_query = "select * from rs_connection WHERE upper_content_id=".$from_content_id." AND is_connected=1";
					$result= mysql_query($select_query,$this->db);

					while($row = mysql_fetch_array($result)){
						$select_current_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$row['lower_content_id'];
						$result_current_rank= mysql_query($select_current_rank,$this->db);
						$row_current_rank = mysql_fetch_array($result_current_rank);

						if($row_current_rank[$this->rs]<($row_from_rank[$this->rs]+$update_step)){
							//Next node just down 1 rank under upper node
							$update_step= abs($row_from_rank[$this->rs]+$update_step+1-$row_current_rank[$this->rs]);
							$this->down_rank($row['lower_content_id'], $update_step);
						}
						else if($row_current_rank[$this->rs]==($row_from_rank[$this->rs]+$update_step))
							$this->down_rank($row['lower_content_id'], 1);
					}
				
					return;
				}
				
				//Check contradiction of new connection
				function is_find_loop($upper_id, $lower_id){
					$select_query = "select id, ".$this->rs." from ff_rs_content WHERE id=".$upper_id." OR id=".$lower_id;
					$result= mysql_query($select_query,$this->db);
					$numrow= mysql_num_rows($result);
		
					while($row = mysql_fetch_array($result)){
						if($row['id']==$upper_id)	$this->upper_rank= $row[$this->rs];
						if($row['id']==$lower_id)	$this->lower_rank= $row[$this->rs];
					}
					
					if($this->upper_rank > $this->lower_rank && $this->lower_rank !=0){
						$temp= $this->upper_rank;
						$this->upper_rank= $this->lower_rank;
						$this->lower_rank= $temp;
						return 1;
					}
					return 0;
				}

				//Find loops
				function find_loops($upper_id, $lower_id){
					$select_query = "select * from rs_connection WHERE upper_content_id=".$upper_id." AND is_connected=1";
					$result= mysql_query($select_query,$this->db);
					//if(!in_array($upper_id, $this->road)){
					$this->road[]= $upper_id;
					//}
					
					while($row = mysql_fetch_array($result)){
						if($row['lower_content_id']== $lower_id){
							$this->road[]= $lower_id;
							return;
						}
						else{
							$select_query_lower_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$row['lower_content_id'];
							$result_lower_rank= mysql_query($select_query_lower_rank,$this->db);

							$row_lower_rank = mysql_fetch_array($result_lower_rank);

							if($this->lower_rank> $row_lower_rank[$this->rs]){
								$this->find_loops($row['lower_content_id'], $lower_id);
							}
						}
					}
					end($this->road);         // move the internal pointer to the end of the array
					$key = key($this->road);  // fetches the key of the element pointed to by the internal pointer

					if($this->road[$key]!= $lower_id) {
						unset($this->road[$key]);
					}
					
					return;
				}

				function update_ranking($upper_id, $lower_id){
					if($this->is_find_loop($upper_id, $lower_id)==1){
						$this->root_id= $lower_id;
						$this->end_id= $upper_id;
						switch($this->check_connection_weight($upper_id, $lower_id)){
							case 1:
								$update_step= abs($this->lower_rank-$this->upper_rank);
								$this->lift_rank($upper_id, $update_step);
								break;
							//case 2:
							//	break;
							case 0:
							case 3://Connection Contradiction is connected
								$this->find_loops($lower_id, $upper_id);
								//$this->road = array_filter($this->road); 
								if(!empty($this->road)){
									//reset counter array
									$this->road = array_values($this->road);
									//$this->road[]= $lower_id;
									print_r($this->road);
									end($this->road);         // move the internal pointer to the end of the array
									$key = key($this->road);  // fetches the key of the element pointed to by the internal pointer
								}
								if(empty($this->road) || $key==0){
									//$this->root_from_id= $upper_id;
									$update_step= $this->lower_rank-$this->upper_rank;
									//Down rank
									$this->lift_rank($upper_id, $update_step);
									$select_query_upper_rank = "select ".$this->rs." from ff_rs_content WHERE id=".$upper_id;
									$result_upper_rank= mysql_query($select_query_upper_rank,$this->db);

									$row_upper_rank = mysql_fetch_array($result_upper_rank);

									$update_step= abs($row_upper_rank[$this->rs]-$this->upper_rank);
									$this->down_rank($lower_id, $update_step+1);
								}
								else if($key>1){
									$arr_road= array();
									//Count roads
									$count_road= 0;
									for($i= 0; $i<= $key; $i++){
										if($this->road[$i]==$upper_id) $count_road++;
									} 
									//Split road branches
									for($i= 0; $i< $count_road; $i++){
										for($j= 0; $j<= $key; $j++){
											$arr_road[$i][]= $this->road[$j];
											if($this->road[$j]==$upper_id) $i++;
										}
									}
									//Redraw all roads
									if($count_road>1){
										for($i= 1; $i< $count_road; $i++){
											while(1){
												if($arr_road[$i][0]==$lower_id) break;
												$select_upper_query = "select * from rs_connection WHERE lower_content_id=".$arr_road[$i][0]." AND is_connected=1";
												$result_upper= mysql_query($select_upper_query,$this->db);

												while($row_upper = mysql_fetch_array($result_upper)){
													if(in_array($row_upper['upper_content_id'], $arr_road[0])){
														array_unshift($arr_road[$i],$row_upper['upper_content_id']);
														break;
													}
												}
											}
										}
									}
									
									var_dump($arr_road);
									
									//Create array of weights of road
									$weight= array();
									for($i= 0; $i< $count_road; $i++){
										$count_nodes= count($arr_road[$i]);
										for($j= 0; $j< $count_nodes; $j++){
											if($j==$count_nodes-1){
												$select_weight_query = "select * from rs_connection WHERE upper_content_id=".$arr_road[$i][$j]." AND lower_content_id=".$arr_road[$i][0]." AND is_connected=1";
											}
											else{
												$select_weight_query = "select * from rs_connection WHERE upper_content_id=".$arr_road[$i][$j]." AND lower_content_id=".$arr_road[$i][$j+1]." AND is_connected=1";
											}
											
											$result_weight= mysql_query($select_weight_query,$this->db);
											while($row_weight = mysql_fetch_array($result_weight)){
												$weight[$i][]= $row_weight['weight'];
											}
											//Find weight of opposite connection
											if($j==$count_nodes-1){
												$select_weight_query = "select * from rs_connection WHERE upper_content_id=".$arr_road[$i][0]." AND lower_content_id=".$arr_road[$i][$j];
											}
											else{
												$select_weight_query = "select * from rs_connection WHERE upper_content_id=".$arr_road[$i][$j+1]." AND lower_content_id=".$arr_road[$i][$j];
											}
											$result_weight= mysql_query($select_weight_query,$this->db);
											while($row_weight = mysql_fetch_array($result_weight)){
												end($weight[$i]);
												$weight[$i][key($weight)]-= $row_weight['weight'];
											}
										}
									}

									var_dump($weight);
									
									$order_process= array();
									for($i= 0; $i< $count_road; $i++){
										array_push($order_process, array_sum($weight[$i]));
									}
									sort($order_process);
									var_dump($order_process);
									//Process Loops with Sum of Value-Weight: Min -> Max
									$break_parts= array();
									$key_bp= 0;
									//$var_count_road= $count_road;
									$var_count_order_process= 0;
									$count_order_process= count($order_process);
									while($count_road!=0){
										$current_loop= array();
										$current_weight_loop= array();
										$seen_min_value= 0;
										for($i= 0; $i< $count_road; $i++){
											///////////

											//echo array_sum($weight[$i])." ".$order_process[$var_count_order_process];
											if(array_sum($weight[$i])== $order_process[$var_count_order_process]){
												//array_shift($order_process);

												$current_loop= $arr_road[$i];
												unset($arr_road[$i]);
												$arr_road= array_values($arr_road);

												$current_weight_loop= $weight[$i];
												unset($weight[$i]);
												$weight= array_values($weight);

												$count_road--;
												$seen_min_value= 1;
												break;
											}//////////
										}
										if($seen_min_value==0){
											if(($count_order_process-1)>$var_count_order_process) $var_count_order_process++;
										}
										else{
											var_dump($current_loop);
											var_dump($current_weight_loop);
											
											$min_weight= min($current_weight_loop);
											$count_connections= count($current_weight_loop);

											if($this->is_a_loop($current_loop, $current_weight_loop)==1){
												for($i= 0; $i< $count_connections; $i++){
													$break_parts[$key_bp][]= $current_loop[$i];
													if($min_weight==$current_weight_loop[$i]){
														if($i==$count_connections-1){
															$update_query= "UPDATE rs_connection SET is_connected=0 WHERE upper_content_id=".$current_loop[$i]." AND lower_content_id=".$current_loop[0];
														}
														else{
															$update_query= "UPDATE rs_connection SET is_connected=0 WHERE upper_content_id=".$current_loop[$i]." AND lower_content_id=".$current_loop[$i+1];
														}
														mysql_query($update_query,$this->db);
														$key_bp++;
													}
												}
												$key_bp++;
											}
										}
										
									}
									
									var_dump($break_parts);
									$count_parts= count($break_parts);
									$select_query = "select id, ".$this->rs." from ff_rs_content WHERE id=".$break_parts[0][0];
									$result= mysql_query($select_query,$this->db);
									$local_upper_rank= 0;
									while($row = mysql_fetch_array($result)){
										$local_upper_rank= $row[$this->rs];
									}
									

									for($i= 0; $i< $count_parts; $i++){
										if($break_parts[$i][0]!=$break_parts[0][0]){
											$select_query = "select id, ".$this->rs." from ff_rs_content WHERE id=".$break_parts[$i][0];
											$result= mysql_query($select_query,$this->db);
											$local_lower_rank= 0;
											while($row = mysql_fetch_array($result)){
												$local_lower_rank= $row[$this->rs];
											}

											$update_step= $local_lower_rank-$local_upper_rank;
											$this->lift_rank($break_parts[$i][0], $update_step);
										}
									}
									//End Process Loops with Sum of Value-Weight: Min -> Max
								}
								break;
						}
					}
					else{
						if($this->upper_rank==0){
								$update_query= "UPDATE ff_rs_content SET ".$this->rs."='".(++$this->upper_rank)."' WHERE id=".$upper_id;
								mysql_query($update_query,$this->db);
								
								if($this->lower_rank==0){
									$this->check_connection_weight($upper_id, $lower_id);
									$this->lower_rank= 2;
									$update_query= "UPDATE ff_rs_content SET ".$this->rs."='".$this->lower_rank."' WHERE id=".$lower_id;
									mysql_query($update_query,$this->db);
								}
								else if($this->lower_rank== 1){
									$this->check_connection_weight($upper_id, $lower_id);
									//decrease rank of lower_rank branch
									$this->down_rank($lower_id, 1);
								}
								else{
									$this->check_connection_weight($upper_id, $lower_id);
								}
						}
						else{
							if($this->lower_rank==0){
								$this->check_connection_weight($upper_id, $lower_id);
								
								$this->lower_rank= $this->upper_rank+1;
								$update_query= "UPDATE ff_rs_content SET ".$this->rs."='".$this->lower_rank."' WHERE id=".$lower_id;
								mysql_query($update_query,$this->db);
							}
							else if($this->lower_rank> $this->upper_rank){
								$this->check_connection_weight($upper_id, $lower_id);
							}
							else if($this->lower_rank== $this->upper_rank){
								$this->check_connection_weight($upper_id, $lower_id);
								$this->down_rank($lower_id, 1);	
							}
						}
					}
				}

				function remove_temp_posts(){
					$delete_query= "DELETE FROM rs_temp_post WHERE posted_time<".$this->get_by_time;
					mysql_query($delete_query,$this->db);
				}

				function activate_new_ranking(){
					$update_query= "UPDATE `settings` SET `value` = '".$this->rs."' WHERE `settings`.`slug` = 'active_ranking'";
					mysql_query($update_query,$this->db);
				}
				
				function is_inspecting(){
					$select_query = "SELECT value FROM `settings` WHERE `slug` = 'is_inspecting'";
					$result= mysql_query($select_query,$this->db);

					while($row = mysql_fetch_array($result)){
						return $row['value'];
					}
				}

				function update_is_inspecting($status){
					$update_query= "UPDATE `settings` SET `value` = '".$status."' WHERE `settings`.`slug` = 'is_inspecting'";
					mysql_query($update_query,$this->db);
				}

				function get_active_ranking(){
					$select_query = "SELECT value FROM `settings` WHERE `slug` = 'active_ranking'";
					$result= mysql_query($select_query,$this->db);

					while($row = mysql_fetch_array($result)){
						if($row['value']=='rank1'){
							$this->rs= 'rank2';
							
						}
						else{
							$this->rs= 'rank1';
						}
					}
				}

				function copy_current_ranking(){
					$select_query = "select * from ff_rs_content";
					$result= mysql_query($select_query,$this->db);

					while($row = mysql_fetch_array($result)){
						if($this->rs=='rank1'){
							$update_query= "UPDATE ff_rs_content SET rank1='".$row['rank2']."' WHERE id=".$row['id'];
							
						}
						else{
							$update_query= "UPDATE ff_rs_content SET rank2='".$row['rank1']."' WHERE id=".$row['id'];
						}
						mysql_query($update_query,$this->db);
					}
				}

				function is_a_loop($loop, $weight_loop){
					$count_connections= count($weight_loop);
					for($i= 0; $i< $count_connections; $i++){
						if($i==$count_connections-1){
							$select_query = "select * from rs_connection WHERE upper_content_id=".$loop[$i]." AND lower_content_id=".$loop[0]." AND is_connected=1";
						}
						else{
							$select_query = "select * from rs_connection WHERE upper_content_id=".$loop[$i]." AND lower_content_id=".$loop[$i+1]." AND is_connected=1";
						}
						$result= mysql_query($select_query,$this->db);
						if(mysql_num_rows($result)==0) return 0;
					}
					return 1;
				}
			}
			//End of Class Genetic Algorithm
		?>
		<?php
			$link = mysql_connect('localhost', 'karapos', 'kara67r8w');
			if (!$link) {
				die('Could not connect: ' . mysql_error());
			}

			$db_selected = mysql_select_db('karapos', $link);
			if (!$db_selected) {
				die ('Can\'t use ranking : ' . mysql_error());
			}
			//Genetic Algorithm Object
			$ga= new GA($link);
			if($ga->is_inspecting()==0){
				$ga->update_is_inspecting(1);
				$select_all_node= "SELECT * FROM `ff_rs_content` ORDER BY ".$this->rs." ASC";
				$result_all_node= mysql_query($select_all_node,$ga->db);
				while($row_node= mysql_fetch_assoc($result_all_node)){
					$select_query_connection = "SELECT * FROM `rs_connection` WHERE `upper_content_id` =".$row_node['id'];
					$result_connection= mysql_query($select_query_connection,$ga->db);
					while($row_connection= mysql_fetch_assoc($result_connection)){
						$ga->update_ranking($row_connection['upper_content_id'], $row_connection['lower_content_id']);
					}
				}
				$ga->activate_new_ranking();
				$ga->update_is_inspecting(0);
			}
			unset($ga);
		?>
   </BODY>
</HTML>